/**
 * 
 */
package org.t2.game.server.module.server.service;

import java.time.LocalDateTime;

import org.gaming.ruler.lifecycle.Lifecycle;
import org.gaming.ruler.schedule.LoopingTask;
import org.gaming.ruler.schedule.ScheduleManager;
import org.gaming.service.service.AbstractService;
import org.gaming.service.timing.TimeSetting;
import org.gaming.tool.DateTimeUtil;
import org.gaming.tool.JvmUtil;
import org.gaming.tool.JvmUtil.MemoryInfo;
import org.gaming.tool.LocalDateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.t2.game.server.foundation.player.PlayerContextManager;
import org.t2.game.server.foundation.starting.ApplicationSettings;
import org.t2.game.server.module.backstage.BackstagePoster;
import org.t2.game.server.module.player.service.PlayerService;
import org.t2.game.server.module.server.model.ServerInfo;

import sh.t2.share.apiutil.GameApi;
import sh.t2.share.module.server.form.ServerRuntimeForm;

/**
 * 
 */
@Service
public class ServerInfoService extends AbstractService<ServerInfo> implements Lifecycle {

	@Autowired
	private ApplicationSettings applicationSettings;
	@Autowired
	private TimeSetting timeSetting;
	@Autowired
	private BackstagePoster backstagePoster;
	@Autowired
	private PlayerService playerService;
	@Autowired
	private PlayerContextManager playerContextManager;
	
	
	public static final String ServerOpenTaskName = "ServerOpenTask";
	
	public ServerInfo getMain() {
		ServerInfo entity = this.repository().getByKeys(applicationSettings.getGameServerId());
		if(entity == null) {
			synchronized (this) {
				entity = this.repository().getByKeys(applicationSettings.getGameServerId());
				if(entity == null) {
					entity = new ServerInfo();
					entity.setId(applicationSettings.getGameServerId());
					if(applicationSettings.getGameOpenType() == 1) {
						//以服务器启动时间为开服时间
						entity.setOpenTime(LocalDateTime.now());
					} else {
						//以开服时间为开服时间
						entity.setOpenTime(LocalDateTime.of(2099, 12, 31, 23, 59));
					}
					this.insert(entity);
				}
			}
		}
		return entity;
	}

	@Override
	public void mergeServer(int mergeDbZoneId) {
		//服务器信息表不需要进行合并
	}
	
	public boolean isOpen() {
		ServerInfo serverInfo = this.getMain();
		return serverInfo.isOpened();
	}
	
	public boolean isMaintain() {
		ServerInfo serverInfo = this.getMain();
		return serverInfo.isMaintain();
	}
	
	/**
	 * 获取服务器已经开服的天数
	 * @return
	 */
	public int getOpenedDay() {
		ServerInfo serverInfo = this.getMain();
		int day = timeSetting.daysFromTimeToNow(serverInfo.getOpenTime());
		if(day < 0) {
			day = 0;
		}
		return day;
	}
	
	protected void runForOpen() {
		ServerInfo serverInfo = this.getMain();
		if(serverInfo.isOpened()) {
			return;
		}
		if(LocalDateTimeUtil.now().isAfter(serverInfo.getOpenTime())) {
			serverInfo.setOpened(true);
			this.update(serverInfo);
			logger.info("服务器{}执行开服逻辑，开服时间{}", applicationSettings.getGameServerId(), serverInfo.getOpenTime());
//			EventBus.post(new ServerOpenEvent());
			ScheduleManager.stopLoopTask(ServerOpenTaskName);
		}
	}
	
	//服务器心跳
	@LoopingTask(name = "ServerHeartBeat", spaceTime = DateTimeUtil.ONE_SECOND_MILLIS * 10, execGroup = 0)
	private void runForHeartBeat() {
		ServerInfo serverInfo = this.getMain();
		long now = DateTimeUtil.currMillis();
		if(serverInfo.getHeartBeatTime() > now) {
			return;
		}
		serverInfo.setHeartBeatTime(now + DateTimeUtil.ONE_MINUTE_MILLIS);
		this.update(serverInfo);
		
		MemoryInfo memoryInfo = JvmUtil.scanMemory();
		
		ServerRuntimeForm form = new ServerRuntimeForm();
		form.setRunning(true);
		form.setPlatformId(applicationSettings.getGameServerPlatformid());
		form.setServerId(applicationSettings.getGameServerId());
		form.setPlayerNum(playerService.getPlayerNum());
		form.setOnlineNum(playerContextManager.onlines().size());
		form.setMaxMemory(memoryInfo.getMaxMemory());
		form.setFreeMemory(memoryInfo.getFreeMemory());
		form.setTotalMemory(memoryInfo.getTotalMemory());
		form.setLeftMemory(memoryInfo.getLeftMemory());
		form.setUsedMemory(memoryInfo.getUsedMemory());
		backstagePoster.jsonPost(GameApi.heartBeat, form);
	}

	@Override
	public void stop() throws Exception {
		ServerRuntimeForm form = new ServerRuntimeForm();
		form.setRunning(false);
		form.setPlatformId(applicationSettings.getGameServerPlatformid());
		form.setServerId(applicationSettings.getGameServerId());
		form.setPlayerNum(playerService.getPlayerNum());
		form.setOnlineNum(playerContextManager.onlines().size());
		form.setMaxMemory("");
		form.setFreeMemory("");
		form.setTotalMemory("");
		form.setLeftMemory("");
		form.setUsedMemory("");
		backstagePoster.jsonPost(GameApi.heartBeat, form);
	}
}
